using System;
using System.Collections.Generic;
using System.Data;
using Castle.MonoRail.Framework;
using Yama.HelloWorld.Dao;
using Yama.HelloWorld.Models;
using Yama.HelloWorld.Rails.Filters;
using Yama.MVC.Dao.Repositories;
using Yama.MVC.MonoRail.Attributes;
using Yama.MVC.NHibernate.Connections;
using Yama.MVC.NHibernate.DataBinder;

namespace Yama.HelloWorld.Rails.Controllers
{
    [Layout("default")]
    [Attributes.HelloWorldResources("Home", "Index", "NoTrans", "ShowVisit", Area="")]
    public class HomeController : Yama.MVC.MonoRail.Controllers.AjaxEnabledController
    {
        public IRepositoryFactory Factory { get; set; }

        /// <summary>
        /// The non-default constructor must be used to switch the databinder implementation
        /// </summary>
        public HomeController(ISessionProvider provider) : base(new NhibernateDataBinder(provider)) { }

        public void Index()
        {
            var newVisit = new Visit
                               {
                                   VisitDate = DateTime.Now,
                                   Url = Request.Url
                               };
            VisitDao.Save(newVisit);

            PropertyBag["visits"] = VisitDao.FindAll(new Dictionary<string, SortDirection>
                                                         {
                                                             {"Id", SortDirection.Descending}
                                                         });
            PropertyBag["count"] = VisitDao.CountVisitsForUrl(Request.Url);
        }

        [TransactionalAction(IsolationLevel.Serializable)]
        public void Index(int changeIsolationLevel)
        {
            Index();
        }

        internal IVisitDao VisitDao
        {
            get { return Factory.CreateVisitDao(); }
        }

        public void ClearVisits()
        {
            VisitDao.DeleteAll();

            RedirectToAction("Index");
        }

        [SkipTransaction]
        public void NoTrans()
        {
            // This action will not cause a transaction to open.
        }
        
        [Filter(ExecuteWhen.BeforeAction, typeof(AccessDatabaseInFilter))]
        public void DbAccessInFilter()
        {
            this.VisitDao.CountVisitsForUrl("");
        }

        /// <summary>
        /// NHDataBindFromKey will not work unless a proper implementation od IDataBinder is used.
        /// Have a look a the HomeCotroller constructor
        /// </summary>
        public void ShowVisit([NHDataBindFromKey] Visit visit)
        {
            // For conveniance NHDataBindFromKey automatically adds
            // the bound element to PropertyBag under the parameter's name
        }
    }
}